package cn.eonshine.cuba.inf.common.util;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Objects;
import java.util.TimeZone;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils{

	/**
	 * 时区时间，夏令时
     * convert any date to cuba date time
     * @param date
     * @return Date
     */
    public static Date getCubaDate(Date date) {
    	//return changeTimeZone(date, TimeZone.getDefault(), getCubaTimeZone());
    	return convert2Date(getZongTime(convert2LocalDateTime(date), getCubaTimeZone().toZoneId()));
    }
	 /**
     * get cuba TimeZone "America/Havana"
     * @return TimeZone
     */
    public static TimeZone getCubaTimeZone() {
    	return TimeZone.getTimeZone("America/Havana");
    }
    
    /**
     * 夏令时时间转换<br>
     * 获取指定时间的 指定时区时间    参照点:默认时区
     * @param time 时间类
     * @param dest 目标时区
     * @return LocalDateTime
     */
  	public static LocalDateTime getZongTime(LocalDateTime time,ZoneId dest) {
  		Objects.requireNonNull(dest);
  		return getZongTime(time, null, dest);
  	}
    /**
     * 夏令时时间转换
     * @param time LocalDateTime时间类
     * @param src 源时区
     * @param dest 转换目标时区
     * @return LocalDateTime
     */
    public static LocalDateTime getZongTime(LocalDateTime time,ZoneId src,ZoneId dest) {
		 //难点就是如何求偏移量
		//这里使用默认时区,在中国的就是中国,在美国的就是美国,这样估计更合适
		Objects.requireNonNull(dest);
		ZonedDateTime z1=null;
		if (src==null) {
			z1 = time.atZone(ZoneId.systemDefault());
		}else{
			z1 = time.atZone(src);
		}
		ZonedDateTime z2 = z1.withZoneSameInstant(dest);
		//处理重叠问题
		long hours = Duration.between(z2.withEarlierOffsetAtOverlap(), z2.withLaterOffsetAtOverlap()).toHours();
		z2= z2.plusHours(hours);
		return z2.toLocalDateTime();
	}
    

    /**
     * 
     * @param localDateTime
     * @return Date
     */
    public static Date convert2Date(LocalDateTime localDateTime) {
		ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        return date;
	}
	/**
	 * 日期Date类转换成 LocalDateTime
	 * @param date 日期类
	 * @return LocalDateTime
	 */
	public static LocalDateTime convert2LocalDateTime(Date date) {
		ZoneId zoneId = ZoneId.systemDefault();
		return convert2LocalDateTime(date, zoneId);
	}
	/**
	 * 日期Date类转换成 LocalDateTime
	 * @param date 日期类
	 * @param zoneId 时区ID
	 * @return LocalDateTime
	 */
	public static LocalDateTime convert2LocalDateTime(Date date, ZoneId zoneId) {
		Instant instant = date.toInstant();
        return instant.atZone(zoneId).toLocalDateTime();
	}
}
